package io.renren.modules.photo.service.impl;

import cn.hutool.core.util.ZipUtil;
import cn.hutool.http.HttpUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.renren.common.constant.Constant;
import io.renren.common.page.PageData;
import io.renren.common.service.impl.BaseServiceImpl;
import io.renren.common.utils.ConvertUtils;
import io.renren.common.utils.Result;
import io.renren.modules.photo.dao.PhotoLabelDao;
import io.renren.modules.photo.dao.PhotoLabelRelaDao;
import io.renren.modules.photo.dto.PhotoLabelDTO;
import io.renren.modules.photo.entity.PhotoLabelEntity;
import io.renren.modules.photo.service.PhotoLabelService;
import io.renren.common.utils.CommonUtil;
import java.io.File;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @Author huan.xu
 * @Date 2022/11/2 11:21
 * @Description 照片信息
 */
@Slf4j
@Service
public class PhotoLabelServiceImpl extends
    BaseServiceImpl<PhotoLabelDao, PhotoLabelEntity> implements
    PhotoLabelService {

  @Autowired
  private PhotoLabelRelaDao photoLabelRelaDao;

  @Value("${attachment.temp-dir}")
  private String tempDir;

  @Override
  public PageData<PhotoLabelDTO> page(Map<String, Object> params) {
    //转换成like
    paramsToLike(params, "name");

    //分页
    IPage<PhotoLabelEntity> page = getPage(params, Constant.CREATE_DATE, false);

    //查询
    List<PhotoLabelDTO> list = baseDao.getInfoList(params);

    if (CollectionUtils.isNotEmpty(list)) {
      list.stream().forEach(photoLabelDTO -> {
        List<Map> photoInfoList = photoLabelRelaDao
            .findPhotoInfoByPhotoLabelId(photoLabelDTO.getId());
        if (CollectionUtils.isNotEmpty(photoInfoList)) {
          photoLabelDTO.setPhotoInfoSize(photoInfoList.size());
        }
      });
    }

    return getPageData(list, page.getTotal(), PhotoLabelDTO.class);
  }

  /**
   * 保存标签
   */
  @Override
  @Transactional(rollbackFor = Exception.class)
  public Result<String> save(PhotoLabelDTO photoLabelDTO) {
    PhotoLabelEntity entity = ConvertUtils
        .sourceToTarget(photoLabelDTO, PhotoLabelEntity.class);

    QueryWrapper<PhotoLabelEntity> queryWrapper = new QueryWrapper<>();
    queryWrapper.lambda().eq(PhotoLabelEntity::getName, photoLabelDTO.getName());
    List<PhotoLabelEntity> photoLabelEntityList = baseDao.selectList(queryWrapper);
    if (CollectionUtils.isNotEmpty(photoLabelEntityList)) {
      throw new RuntimeException("标签名称重复");
    }
    baseDao.insert(entity);
    return new Result<>();
  }

  /**
   * 修改标签
   */
  @Override
  @Transactional(rollbackFor = Exception.class)
  public Result<String> update(PhotoLabelDTO dto) {
    PhotoLabelEntity photoLabelEntity = ConvertUtils
        .sourceToTarget(dto, PhotoLabelEntity.class);

    QueryWrapper<PhotoLabelEntity> queryWrapper = new QueryWrapper<>();
    queryWrapper.lambda()
        .eq(PhotoLabelEntity::getName, dto.getName())
        .ne(PhotoLabelEntity::getId, photoLabelEntity.getId());
    List<PhotoLabelEntity> photoLabelEntityList = baseDao.selectList(queryWrapper);
    if (CollectionUtils.isNotEmpty(photoLabelEntityList)) {
      throw new RuntimeException("标签名称重复");
    }
    baseDao.updateById(photoLabelEntity);
    return new Result<>();
  }

  @Override
  public void delete(Long[] ids) {
    baseDao.deleteBatchIds(Arrays.asList(ids));
  }

  /**
   * 根据标签名称组装查询框数据
   */
  @Override
  public List<Map> getSelectOptions(String query) {
    List<PhotoLabelEntity> photoLabelEntityList = null;
    QueryWrapper<PhotoLabelEntity> queryWrapper = null;
    if (StringUtils.isNotBlank(query)) {
      queryWrapper = new QueryWrapper<>();
      queryWrapper.lambda().like(PhotoLabelEntity::getName, query);

    }
    photoLabelEntityList = baseDao.selectList(queryWrapper);

    List<Map> returnList = photoLabelEntityList.stream()
        .map(label -> {
          Map labelMap = new HashMap(16);
          labelMap.put("id", label.getId());
          labelMap.put("name", label.getName());
          return labelMap;
        }).collect(Collectors.toList());
    return returnList;
  }

  /**
   * 根据id查询
   */
  @Override
  public PhotoLabelDTO getById(Long id) {
    PhotoLabelEntity photoLabelEntity = baseDao.selectById(id);
    return ConvertUtils.sourceToTarget(photoLabelEntity, PhotoLabelDTO.class);
  }

  /**
   * 下载标签下的所有照片
   */
  @Override
  public void downloadLabelPhoto(Long labelId, HttpServletRequest request,
      HttpServletResponse response) {
    if (labelId == null) {
      throw new RuntimeException("标签ID为空");
    }
    PhotoLabelEntity photoLabelEntity = baseDao.selectById(labelId);
    if (photoLabelEntity == null) {
      throw new RuntimeException("获取标签信息失败");
    }
    List<Map> photoInfoList = photoLabelRelaDao.findPhotoInfoByPhotoLabelId(labelId);
    if (CollectionUtils.isEmpty(photoInfoList)) {
      throw new RuntimeException("此标签下无照片");
    }
    Date newDate = new Date();
    String times = newDate.getTime() + "";
    if (!tempDir.endsWith(File.separator)) {
      tempDir = tempDir + File.separator;
    }
    // 生成本地文件夹
    String localDirPath = tempDir + times;
    log.info("临时文件夹路径：{}", localDirPath);
    File localDir = new File(localDirPath);
    if (!localDir.exists()) {
      localDir.mkdirs();
    }
    // 1.所有的附件都下载到本地
    photoInfoList.stream()
        .filter(photoInfoMap -> {
          String downloadUrl = MapUtils.getString(photoInfoMap, "download_url");
          if (StringUtils.isNotBlank(downloadUrl)) {
            return true;
          }
          return false;
        })
        .forEach(photoInfoMap -> {
          String downloadUrl = MapUtils.getString(photoInfoMap, "download_url");
          String fileName = MapUtils.getString(photoInfoMap, "infoName");
          String destPath = localDir.getPath() + File.separator + fileName;
          log.info("照片路径：{}", destPath);
          HttpUtil.downloadFileFromUrl(downloadUrl, destPath);
        });
    // 2.生成zip包
    String zipLocalPath = tempDir + times + ".zip";
    log.info("zip路径：{}", zipLocalPath);
    ZipUtil.zip(localDir.getPath(), zipLocalPath);
    // 3.下载zip包
    String originalFileName = photoLabelEntity.getName() + "_照片_" + times;
    CommonUtil.downloadFile(originalFileName,new File(zipLocalPath),response,request);
  }
}
